package com.im.service.friendship.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.im.codec.pack.friendship.*;
import com.im.service.config.AppConfig;
import com.im.common.constant.Constants;
import com.im.common.enums.*;
import com.im.common.enums.command.FriendshipEventCommand;
import com.im.common.enums.exception.FriendShipErrorCode;
import com.im.common.enums.exception.UserErrorCode;
import com.im.common.exception.BusinessException;
import com.im.common.model.RequestBase;
import com.im.common.model.RestResponse;
import com.im.common.model.SyncReq;
import com.im.common.model.SyncResp;
import com.im.service.friendship.entity.FriendShip;
import com.im.service.friendship.mapper.ImFriendShipMapper;
import com.im.service.friendship.model.callback.AddFriendAfterCallbackDto;
import com.im.service.friendship.model.callback.AddFriendBlackAfterCallbackDto;
import com.im.service.friendship.model.callback.DeleteFriendAfterCallbackDto;
import com.im.service.friendship.model.req.*;
import com.im.service.friendship.model.resp.CheckFriendShipResp;
import com.im.service.friendship.model.resp.ImportFriendShipResp;
import com.im.service.friendship.service.ImFriendService;
import com.im.service.friendship.service.ImFriendShipRequestService;
import com.im.service.user.entity.ImUserDataEntity;
import com.im.service.user.service.ImUserService;
import com.im.service.utils.CallbackService;
import com.im.service.utils.MessageProducer;
import com.im.service.utils.RedisSeq;
import com.im.service.utils.WriteUserSeq;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class ImFriendServiceImpl extends ServiceImpl<ImFriendShipMapper, FriendShip> implements ImFriendService {

    @Autowired
    ImFriendShipMapper imFriendShipMapper;
    @Autowired
    ImUserService imUserService;
    @Autowired
    AppConfig appConfig;
    @Autowired
    CallbackService callbackService;
    @Autowired
    MessageProducer messageProducer;
    @Autowired
    ImFriendService imFriendService;
    @Autowired
    ImFriendShipRequestService imFriendShipRequestService;
    @Autowired
    RedisSeq redisSeq;
    @Autowired
    WriteUserSeq writeUserSeq;

    @Override
    public ImportFriendShipResp importFriendShip(ImporFriendShipReq req) {
        // 判断导入的好友信息数量是否超过 100，如果超过则抛出业务异常
        if (req.getFriendItem().size() > 100) {
            throw new BusinessException(FriendShipErrorCode.IMPORT_SIZE_BEYOND);
        }

        // 创建 ImportFriendShipResp 对象
        ImportFriendShipResp resp = new ImportFriendShipResp();
        // 创建 successId 和 errorId 集合，用于存储导入成功和失败的好友信息 ID
        List<String> successId = new ArrayList<>();
        List<String> errorId = new ArrayList<>();

        // 遍历导入的好友信息列表
        for (ImporFriendShipReq.ImportFriendDto dto : req.getFriendItem()) {
            // 创建 FriendShip 对象，并将导入的好友信息复制到该对象中
            FriendShip entity = new FriendShip();
            BeanUtils.copyProperties(dto, entity);
            // 设置好友信息的 AppId 和 FromId
            entity.setAppId(req.getAppId());
            entity.setFromId(req.getFromId());
            try {
                // 将好友信息插入数据库中
                int insert = imFriendShipMapper.insert(entity);
                // 如果插入成功，则将好友信息 ID 存入 successId 集合中
                if (insert == 1) {
                    successId.add(dto.getToId());
                } else {
                    // 如果插入失败，则将好友信息 ID 存入 errorId 集合中
                    errorId.add(dto.getToId());
                }
            } catch (Exception e) {
                // 如果插入时出现异常，则将好友信息 ID 存入 errorId 集合中
                e.printStackTrace();
                errorId.add(dto.getToId());
            }
        }

        // 将成功和失败的好友信息 ID 分别设置到 ImportFriendShipResp 对象中
        resp.setErrorId(errorId);
        resp.setSuccessId(successId);

        // 返回 ImportFriendShipResp 对象
        return resp;
    }


    @Override
    public void addFriend(AddFriendReq req) {
        // 获取发起添加好友请求的用户信息
        ImUserDataEntity fromInfo = imUserService.getSingleUserInfo(req.getFromId(), req.getAppId());
        if (fromInfo == null) {
            // 如果发起请求的用户不存在，则抛出业务异常
            throw new BusinessException(UserErrorCode.USER_IS_NOT_EXIST);
        }

        // 获取被添加好友的用户信息
        ImUserDataEntity toInfo = imUserService.getSingleUserInfo(req.getToItem().getToId(), req.getAppId());
        if (toInfo == null) {
            // 如果被添加的用户不存在，则抛出业务异常
            throw new BusinessException(UserErrorCode.USER_IS_NOT_EXIST);
        }

        // 如果配置了添加好友前回调，则调用回调服务
        if (appConfig.isAddFriendBeforeCallback()) {
            RestResponse callbackResp = callbackService.beforeCallback(
                    req.getAppId(),
                    Constants.CallbackCommand.AddFriendBefore,
                    JSONObject.toJSONString(req));
            if (!callbackResp.isStatus()) {
                // 如果回调服务返回失败，则抛出业务异常
                throw new BusinessException(callbackResp.getMessage());
            }
        }

        // 判断被添加好友的用户是否允许被添加
        if (toInfo.getFriendAllowType() != null && toInfo.getFriendAllowType() == AllowFriendTypeEnum.NOT_NEED.getCode()) {
            // 如果允许被添加，则执行添加好友操作
            this.doAddFriend(req, req.getFromId(), req.getToItem(), req.getAppId());
        } else {
            // 如果不允许被添加，则插入一条好友申请的数据
            QueryWrapper<FriendShip> query = new QueryWrapper<>();
            query.eq("app_id", req.getAppId());
            query.eq("from_id", req.getFromId());
            query.eq("to_id", req.getToItem().getToId());
            FriendShip fromItem = imFriendShipMapper.selectOne(query);
            if (fromItem == null || fromItem.getStatus() != FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode()) {
                // 如果之前没有好友关系，则插入一条好友申请的数据
                imFriendShipRequestService.addFienshipRequest(req.getFromId(), req.getToItem(), req.getAppId());
            } else {
                // 如果之前已经存在好友关系，则抛出业务异常
                throw new BusinessException(FriendShipErrorCode.TO_IS_YOUR_FRIEND);
            }
        }
    }

    @Override
    public void updateFriend(UpdateFriendReq req) {
        // 获取发送方用户信息
        ImUserDataEntity fromInfo = imUserService.getSingleUserInfo(req.getFromId(), req.getAppId());
        // 如果发送方用户信息为空，抛出用户不存在的业务异常
        if (fromInfo == null) {
            throw new BusinessException(UserErrorCode.USER_IS_NOT_EXIST);
        }
        // 获取接收方用户信息
        ImUserDataEntity toInfo = imUserService.getSingleUserInfo(req.getToItem().getToId(), req.getAppId());
        // 如果接收方用户信息为空，抛出用户不存在的业务异常
        if (toInfo == null) {
            throw new BusinessException(UserErrorCode.USER_IS_NOT_EXIST);
        }
        // 执行好友信息的更新操作
        this.doUpdate(req.getFromId(), req.getToItem(), req.getAppId());
        // 构造好友信息更新的消息实体
        UpdateFriendPack updateFriendPack = new UpdateFriendPack();
        updateFriendPack.setRemark(req.getToItem().getRemark());
        updateFriendPack.setToId(req.getToItem().getToId());
        // 将好友信息更新的消息实体发送给发送方用户
        messageProducer.sendToUser(
                req.getFromId(),
                req.getClientType(),
                req.getImei(),
                FriendshipEventCommand.FRIEND_UPDATE,
                updateFriendPack,
                req.getAppId()
        );
        // 如果配置了在回调之后再修改好友信息，构造回调相关的参数并执行回调操作
        if (appConfig.isModifyFriendAfterCallback()) {
            AddFriendAfterCallbackDto callbackDto = new AddFriendAfterCallbackDto();
            callbackDto.setFromId(req.getFromId());
            callbackDto.setToItem(req.getToItem());
            callbackService.beforeCallback(
                    req.getAppId(),
                    Constants.CallbackCommand.UpdateFriendAfter,
                    JSONObject.toJSONString(callbackDto)
            );
        }
    }

    @Transactional
    public void doUpdate(String fromId, FriendDto dto, Integer appId) {
        // 获取一个序列号
        long seq = redisSeq.doGetSeq(appId + ":" + Constants.SeqConstants.Friendship);
        // 创建一个 UpdateWrapper 对象，用于更新 FriendShip 表中的记录
        UpdateWrapper<FriendShip> updateWrapper = new UpdateWrapper<>();
        // 设置要更新的字段和对应的值
        updateWrapper.lambda().set(FriendShip::getAddSource, dto.getAddSource())
                .set(FriendShip::getExtra, dto.getExtra())
                .set(FriendShip::getFriendSequence, seq)
                .set(FriendShip::getRemark, dto.getRemark())
                .eq(FriendShip::getAppId, appId)
                .eq(FriendShip::getToId, dto.getToId())
                .eq(FriendShip::getFromId, fromId);

        // 执行更新操作
        int update = imFriendShipMapper.update(null, updateWrapper);
        if (update == 1) {
            // 如果更新成功，则写入用户序列号
            writeUserSeq.writeUserSeq(appId, fromId, Constants.SeqConstants.Friendship, seq);
        }
    }

    /**
     * 添加好友方法
     *
     * @param requestBase 请求基础信息
     * @param fromId      发起添加好友的用户ID
     * @param dto         好友信息
     * @param appId       应用ID
     */
    @Transactional
    public void doAddFriend(RequestBase requestBase, String fromId, FriendDto dto, Integer appId) {
        // 查询是否已经存在好友关系
        QueryWrapper<FriendShip> query = new QueryWrapper<>();
        query.eq("app_id", appId);
        query.eq("from_id", fromId);
        query.eq("to_id", dto.getToId());
        FriendShip fromItem = imFriendShipMapper.selectOne(query);
        long seq = 0L;
        if (fromItem == null) {
            // 如果不存在好友关系，则添加好友
            fromItem = new FriendShip();
            seq = redisSeq.doGetSeq(appId + ":" + Constants.SeqConstants.Friendship);
            fromItem.setAppId(appId);
            fromItem.setFriendSequence(seq);
            fromItem.setFromId(fromId);
            BeanUtils.copyProperties(dto, fromItem);
            fromItem.setStatus(FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode());
            fromItem.setCreateTime(System.currentTimeMillis());
            int insert = imFriendShipMapper.insert(fromItem);
            if (insert != 1) {
                throw new BusinessException(FriendShipErrorCode.ADD_FRIEND_ERROR);
            }
            writeUserSeq.writeUserSeq(appId, fromId, Constants.SeqConstants.Friendship, seq);
        } else {
            // 如果已经存在好友关系，则修改好友信息
            if (fromItem.getStatus() == FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode()) {
                throw new BusinessException(FriendShipErrorCode.TO_IS_YOUR_FRIEND);
            } else {
                FriendShip update = new FriendShip();
                if (StringUtils.isNotBlank(dto.getAddSource())) {
                    update.setAddSource(dto.getAddSource());
                }
                if (StringUtils.isNotBlank(dto.getRemark())) {
                    update.setRemark(dto.getRemark());
                }
                if (StringUtils.isNotBlank(dto.getExtra())) {
                    update.setExtra(dto.getExtra());
                }
                seq = redisSeq.doGetSeq(appId + ":" + Constants.SeqConstants.Friendship);
                update.setFriendSequence(seq);
                update.setStatus(FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode());
                int result = imFriendShipMapper.update(update, query);
                if (result != 1) {
                    throw new BusinessException(FriendShipErrorCode.ADD_FRIEND_ERROR);
                }
                writeUserSeq.writeUserSeq(appId, fromId, Constants.SeqConstants.Friendship, seq);
            }
        }
        // 添加好友关系的另一方
        QueryWrapper<FriendShip> toQuery = new QueryWrapper<>();
        toQuery.eq("app_id", appId);
        toQuery.eq("from_id", dto.getToId());
        toQuery.eq("to_id", fromId);
        FriendShip toItem = imFriendShipMapper.selectOne(toQuery);
        if (toItem == null) {
            toItem = new FriendShip();
            toItem.setAppId(appId);
            toItem.setFromId(dto.getToId());
            BeanUtils.copyProperties(dto, toItem);
            toItem.setToId(fromId);
            toItem.setFriendSequence(seq);
            toItem.setStatus(FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode());
            toItem.setCreateTime(System.currentTimeMillis());
            int insert = imFriendShipMapper.insert(toItem);
            writeUserSeq.writeUserSeq(appId, dto.getToId(), Constants.SeqConstants.Friendship, seq);
        } else {
            if (FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode() != toItem.getStatus()) {
                FriendShip update = new FriendShip();
                update.setFriendSequence(seq);
                update.setStatus(FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode());
                imFriendShipMapper.update(update, toQuery);
                writeUserSeq.writeUserSeq(appId, dto.getToId(), Constants.SeqConstants.Friendship, seq);
            }
        }
        // 发送添加好友通知
        AddFriendPack addFriendPack = new AddFriendPack();
        BeanUtils.copyProperties(fromItem, addFriendPack);
        addFriendPack.setSequence(seq);
        if (requestBase != null) {
            messageProducer.sendToUser(fromId, requestBase.getClientType(), requestBase.getImei(), FriendshipEventCommand.FRIEND_ADD, addFriendPack, requestBase.getAppId()
            );
        } else {
            messageProducer.sendToUser(fromId, FriendshipEventCommand.FRIEND_ADD, addFriendPack, requestBase.getAppId());
        }
        AddFriendPack addFriendToPack = new AddFriendPack();
        BeanUtils.copyProperties(toItem, addFriendPack);
        messageProducer.sendToUser(toItem.getFromId(), FriendshipEventCommand.FRIEND_ADD, addFriendToPack, requestBase.getAppId());
        // 添加好友后的回调
        if (appConfig.isAddFriendAfterCallback()) {
            AddFriendAfterCallbackDto callbackDto = new AddFriendAfterCallbackDto();
            callbackDto.setFromId(fromId);
            callbackDto.setToItem(dto);
            callbackService.beforeCallback(appId, Constants.CallbackCommand.AddFriendAfter, JSONObject.toJSONString(callbackDto));
        }
    }


    @Override
    public void deleteFriend(DeleteFriendReq req) {
        QueryWrapper<FriendShip> query = new QueryWrapper<>();
        query.eq("app_id", req.getAppId());
        query.eq("from_id", req.getFromId());
        query.eq("to_id", req.getToId());
        FriendShip fromItem = imFriendShipMapper.selectOne(query);
        if (fromItem == null) {
            throw new BusinessException(FriendShipErrorCode.TO_IS_NOT_YOUR_FRIEND);
        } else {
            if (fromItem.getStatus() != null && fromItem.getStatus() == FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode()) {
                FriendShip update = new FriendShip();
                long seq = redisSeq.doGetSeq(req.getAppId() + ":" + Constants.SeqConstants.Friendship);
                update.setFriendSequence(seq);
                update.setStatus(FriendShipStatusEnum.FRIEND_STATUS_DELETE.getCode());
                imFriendShipMapper.update(update, query);
                writeUserSeq.writeUserSeq(req.getAppId(), req.getFromId(), Constants.SeqConstants.Friendship, seq);
                DeleteFriendPack deleteFriendPack = new DeleteFriendPack();
                deleteFriendPack.setFromId(req.getFromId());
                deleteFriendPack.setSequence(seq);
                deleteFriendPack.setToId(req.getToId());
                messageProducer.sendToUser(req.getFromId(), req.getClientType(), req.getImei(), FriendshipEventCommand.FRIEND_DELETE, deleteFriendPack, req.getAppId());

                //之后回调
                if (appConfig.isAddFriendAfterCallback()) {
                    DeleteFriendAfterCallbackDto callbackDto = new DeleteFriendAfterCallbackDto();
                    callbackDto.setFromId(req.getFromId());
                    callbackDto.setToId(req.getToId());
                    callbackService.beforeCallback(req.getAppId(), Constants.CallbackCommand.DeleteFriendAfter, JSONObject.toJSONString(callbackDto));
                }

            } else {
                throw new BusinessException(FriendShipErrorCode.FRIEND_IS_DELETED);
            }
        }
    }

    @Override
    public void deleteAllFriend(DeleteFriendReq req) {
        // 构建查询条件
        QueryWrapper<FriendShip> query = new QueryWrapper<>();
        query.eq("app_id", req.getAppId()); // 查询条件：appId 等于 req 中的 appId
        query.eq("from_id", req.getFromId()); // 查询条件：fromId 等于 req 中的 fromId
        query.eq("status", FriendShipStatusEnum.FRIEND_STATUS_NORMAL.getCode()); // 查询条件：status 等于 FRIEND_STATUS_NORMAL
        // 构建更新数据
        FriendShip update = new FriendShip();
        update.setStatus(FriendShipStatusEnum.FRIEND_STATUS_DELETE.getCode()); // 更新数据：status 等于 FRIEND_STATUS_DELETE
        // 执行更新操作
        imFriendShipMapper.update(update, query);
        // 构建删除所有好友的通知消息
        DeleteAllFriendPack deleteFriendPack = new DeleteAllFriendPack();
        deleteFriendPack.setFromId(req.getFromId());
        // 发送删除所有好友的通知消息
        messageProducer.sendToUser(req.getFromId(), req.getClientType(), req.getImei(), FriendshipEventCommand.FRIEND_ALL_DELETE, deleteFriendPack, req.getAppId());
    }


    @Override
    public List<FriendShip> getAllFriendShip(GetAllFriendShipReq req) {
        QueryWrapper<FriendShip> query = new QueryWrapper<>();
        // 根据请求参数设置查询条件
        query.eq("app_id", req.getAppId());
        query.eq("from_id", req.getFromId());
        // 执行查询并返回结果
        List<FriendShip> list = list(query);
        return list;
    }


    @Override
    public FriendShip getRelation(GetRelationReq req) {
        QueryWrapper<FriendShip> query = new QueryWrapper<>();
        // 根据请求参数设置查询条件
        query.eq("app_id", req.getAppId());
        query.eq("from_id", req.getFromId());
        query.eq("to_id", req.getToId());
        // 执行查询并返回结果
        FriendShip entity = imFriendShipMapper.selectOne(query);
        // 判断结果是否为空，如果为空则抛出业务异常
        if (entity == null) {
            throw new BusinessException(FriendShipErrorCode.REPEATSHIP_IS_NOT_EXIST);
        }
        return entity;
    }

    @Override
    /**
     * 检查好友关系是否在黑名单中
     *
     * @param req 检查好友关系的请求参数，包括被检查的好友 ID 列表、检查类型（单向还是双向）和发起检查的用户 ID
     * @return 包含每个被检查好友关系的检查结果的列表，如果某个好友关系不存在则默认为不在黑名单中
     */
    public List<CheckFriendShipResp> checkBlck(CheckFriendShipReq req) {
        // 将被检查的好友 ID 列表转换为 Map，初始值为 0
        Map<String, Integer> toIdMap = req.getToIds().stream().collect(Collectors.toMap(Function.identity(), s -> 0));
        // 定义结果列表
        List<CheckFriendShipResp> result = new ArrayList<>();
        // 根据检查类型调用不同的 Mapper 方法查询好友关系黑名单
        if (req.getCheckType() == CheckFriendShipTypeEnum.SINGLE.getType()) {
            result = imFriendShipMapper.checkFriendShipBlack(req);
        } else {
            result = imFriendShipMapper.checkFriendShipBlackBoth(req);
        }
        // 将查询结果转换为 Map，以被检查好友 ID 为键，好友关系状态为值
        Map<String, Integer> collect = result.stream().collect(Collectors.toMap(CheckFriendShipResp::getToId, CheckFriendShipResp::getStatus));
        // 遍历被检查好友 ID Map，如果某个好友关系不存在则将其添加到结果列表中
        for (String toId :
                toIdMap.keySet()) {
            if (!collect.containsKey(toId)) {
                CheckFriendShipResp checkFriendShipResp = new CheckFriendShipResp();
                checkFriendShipResp.setToId(toId);
                checkFriendShipResp.setFromId(req.getFromId());
                checkFriendShipResp.setStatus(toIdMap.get(toId));
                result.add(checkFriendShipResp);
            }
        }
        // 返回结果列表
        return result;
    }

    @Override
    public SyncResp<FriendShip> syncFriendshipList(SyncReq req) {
        // 如果最大限制超过 100，则将最大限制设置为 100。
        if (req.getMaxLimit() > 100) {
            req.setMaxLimit(100);
        }
        SyncResp<FriendShip> resp = new SyncResp<>();
        // 构造查询条件
        QueryWrapper<FriendShip> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("from_id", req.getOperator());
        queryWrapper.gt("friend_sequence", req.getLastSequence());
        queryWrapper.eq("app_id", req.getAppId());
        queryWrapper.last(" limit " + req.getMaxLimit());
        queryWrapper.orderByAsc("friend_sequence");
        // 执行查询
        List<FriendShip> list = imFriendShipMapper.selectList(queryWrapper);

        if (!CollectionUtils.isEmpty(list)) {
            // 如果查询结果非空，则设置 SyncResp 对象的属性
            FriendShip maxSeqEntity = list.get(list.size() - 1);
            resp.setDataList(list);
            //设置最大序列号
            Long friendShipMaxSeq = imFriendShipMapper.getFriendShipMaxSeq(req.getAppId(), req.getOperator());
            resp.setMaxSequence(friendShipMaxSeq);
            //设置是否拉取完毕
            resp.setCompleted(maxSeqEntity.getFriendSequence() >= friendShipMaxSeq);
            return resp;
        }
        // 如果查询结果为空，则设置 SyncResp 对象的 completed 属性为 true
        resp.setCompleted(true);
        return resp;
    }

    @Override
    public List<String> getAllFriendId(String userId, Integer appId) {
        return imFriendShipMapper.getAllFriendId(userId, appId);
    }

    @Override
    public ImUserDataEntity addBlack(AddFriendShipBlackReq req) throws BusinessException {
        //获取发送方用户信息
        ImUserDataEntity fromInfo = imUserService.getSingleUserInfo(req.getFromId(), req.getAppId());
        if (fromInfo != null) {
            return fromInfo;
        }
        //获取接收方用户信息
        ImUserDataEntity toInfo = imUserService.getSingleUserInfo(req.getToId(), req.getAppId());
        if (toInfo != null) {
            return toInfo;
        }
        //构建查询条件
        QueryWrapper<FriendShip> query = new QueryWrapper<>();
        query.eq("app_id", req.getAppId());
        query.eq("from_id", req.getFromId());
        query.eq("to_id", req.getToId());
        //查询好友关系
        FriendShip fromItem = imFriendShipMapper.selectOne(query);
        Long seq = 0L;
        if (fromItem == null) {
            //如果好友关系不存在，则添加好友关系
            seq = redisSeq.doGetSeq(req.getAppId() + ":" + Constants.SeqConstants.Friendship);
            fromItem = new FriendShip();
            fromItem.setFromId(req.getFromId());
            fromItem.setToId(req.getToId());
            fromItem.setFriendSequence(seq);
            fromItem.setAppId(req.getAppId());
            fromItem.setBlack(FriendShipStatusEnum.BLACK_STATUS_BLACKED.getCode());
            fromItem.setCreateTime(System.currentTimeMillis());
            int insert = imFriendShipMapper.insert(fromItem);
            if (insert != 1) {
                //添加失败则抛出异常
                throw new BusinessException(FriendShipErrorCode.ADD_FRIEND_ERROR);
            }
            writeUserSeq.writeUserSeq(req.getAppId(), req.getFromId(), Constants.SeqConstants.Friendship, seq);

        } else {
            //如果好友关系存在，则判断好友关系状态
            if (fromItem.getBlack() != null && fromItem.getBlack() == FriendShipStatusEnum.BLACK_STATUS_BLACKED.getCode()) {
                //如果已经拉黑，则抛出异常
                throw new BusinessException(FriendShipErrorCode.FRIEND_IS_BLACK);
            } else {
                //修改好友关系状态为拉黑
                seq = redisSeq.doGetSeq(req.getAppId() + ":" + Constants.SeqConstants.Friendship);
                FriendShip update = new FriendShip();
                update.setFriendSequence(seq);
                update.setBlack(FriendShipStatusEnum.BLACK_STATUS_BLACKED.getCode());
                int result = imFriendShipMapper.update(update, query);
                if (result != 1) {
                    //修改失败则抛出异常
                    throw new BusinessException(FriendShipErrorCode.ADD_BLACK_ERROR);
                }
                writeUserSeq.writeUserSeq(req.getAppId(), req.getFromId(), Constants.SeqConstants.Friendship, seq);
            }
        }
        //构建添加黑名单关系的通知消息
        AddFriendBlackPack addFriendBlackPack = new AddFriendBlackPack();
        addFriendBlackPack.setFromId(req.getFromId());
        addFriendBlackPack.setSequence(seq);
        addFriendBlackPack.setToId(req.getToId());
        //发送添加黑名单关系的通知消息
        messageProducer.sendToUser(req.getFromId(), req.getClientType(), req.getImei(), FriendshipEventCommand.FRIEND_BLACK_ADD, addFriendBlackPack, req.getAppId());
        //回调
        if (appConfig.isAddFriendShipBlackAfterCallback()) {
            AddFriendBlackAfterCallbackDto callbackDto = new AddFriendBlackAfterCallbackDto();
            callbackDto.setFromId(req.getFromId());
            callbackDto.setToId(req.getToId());
            callbackService.beforeCallback(req.getAppId(), Constants.CallbackCommand.AddBlackAfter, JSONObject.toJSONString(callbackDto));
        }

        return null;
    }

    @Override
    public void deleteBlack(DeleteBlackReq req) throws BusinessException {
        // 查询该好友是否在黑名单中
        QueryWrapper queryFrom = new QueryWrapper<>()
                .eq("from_id", req.getFromId())
                .eq("app_id", req.getAppId())
                .eq("to_id", req.getToId());
        FriendShip fromItem = imFriendShipMapper.selectOne(queryFrom);
        if (fromItem.getBlack() != null && fromItem.getBlack() == FriendShipStatusEnum.BLACK_STATUS_NORMAL.getCode()) {
            throw new BusinessException(FriendShipErrorCode.FRIEND_IS_NOT_YOUR_BLACK);
        }
        // 生成好友关系序列号
        long seq = redisSeq.doGetSeq(req.getAppId() + ":" + Constants.SeqConstants.Friendship);
        // 更新好友关系表
        FriendShip update = new FriendShip();
        update.setFriendSequence(seq);
        update.setBlack(FriendShipStatusEnum.BLACK_STATUS_NORMAL.getCode());
        int update1 = imFriendShipMapper.update(update, queryFrom);
        // 如果更新成功，进行一系列操作
        if (update1 == 1) {
            // 写入用户序列号
            writeUserSeq.writeUserSeq(req.getAppId(), req.getFromId(), Constants.SeqConstants.Friendship, seq);
            // 发送删除好友关系的消息
            DeleteBlackPack deleteFriendPack = new DeleteBlackPack();
            deleteFriendPack.setFromId(req.getFromId());
            deleteFriendPack.setSequence(seq);
            deleteFriendPack.setToId(req.getToId());
            messageProducer.sendToUser(req.getFromId(), req.getClientType(), req.getImei(), FriendshipEventCommand.FRIEND_BLACK_DELETE, deleteFriendPack, req.getAppId());
            // 如果设置了回调，执行回调操作
            if (appConfig.isAddFriendShipBlackAfterCallback()) {
                AddFriendBlackAfterCallbackDto callbackDto = new AddFriendBlackAfterCallbackDto();
                callbackDto.setFromId(req.getFromId());
                callbackDto.setToId(req.getToId());
                callbackService.beforeCallback(req.getAppId(), Constants.CallbackCommand.DeleteBlack, JSONObject.toJSONString(callbackDto));
            }
        }
    }

    @Override
    public List<CheckFriendShipResp> checkFriendship(CheckFriendShipReq req) {
        // 初始化结果 Map，将 toIds 中的每个 id 都作为 key，value 初始值为 0
        Map<String, Integer> result = req.getToIds().stream().collect(Collectors.toMap(Function.identity(), s -> 0));
        // 初始化响应列表
        List<CheckFriendShipResp> resp = new ArrayList<>();
        // 根据检查类型分别查询好友关系
        if (req.getCheckType() == CheckFriendShipTypeEnum.SINGLE.getType()) {
            resp = imFriendShipMapper.checkFriendShip(req);
        } else {
            resp = imFriendShipMapper.checkFriendShipBoth(req);
        }
        // 将响应列表转换为 Map，以 toId 为 key，status 为 value
        Map<String, Integer> collect = resp.stream().collect(Collectors.toMap(CheckFriendShipResp::getToId, CheckFriendShipResp::getStatus));
        // 遍历结果 Map，如果响应 Map 中不包含该 key，则将该 key 对应的 value 设置为 result 中对应的 value，并添加到响应列表中
        for (String toId : result.keySet()) {
            if (!collect.containsKey(toId)) {
                CheckFriendShipResp checkFriendShipResp = new CheckFriendShipResp();
                checkFriendShipResp.setFromId(req.getFromId());
                checkFriendShipResp.setToId(toId);
                checkFriendShipResp.setStatus(result.get(toId));
                resp.add(checkFriendShipResp);
            }
        }
        // 返回响应列表
        return resp;
    }

}
